/*================================================================
*   Copyright (C) 2024 baichao All rights reserved.
*
*   文件名称：ftok.c
*   创 建 者：baichao
*   创建日期：2024年05月14日
*   描述：ftok接口把通过path-name获取的信息和传入的第二个参数的低8位糅合在一起，得到一个整型的IPC key值，算法如下：
*        ———————————————————————————————————————————————————————————————————————————————————
*        | proj_id的低8位 | 文件所在设备的次设备号的低8位 | pathname对应文件的inode号的最低16位 |
*        ———————————————————————————————————————————————————————————————————————————————————
*
================================================================*/

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
  key_t myKey;
  int msgid;

  // 文件路径和项目ID
  char __pathname[] = "/home/baichao/code/cpp_test/linux/process/ipc/ftok.c";
  int __proj_id = 0x1234;

  // 获取文件状态
  struct stat stat_buf;
  stat(__pathname, &stat_buf);

  // 使用ftok生成键值
  myKey = ftok(__pathname, __proj_id);
  if ((myKey == (key_t)-1) && (errno == ENOENT)) {
    perror("ftok failed");
    return 1;  // 处理错误
  }

  printf("__proj_id: %lx, st_dev : %lx, st_inode : %lx , key : %x \n",__proj_id & 0xFF, stat_buf.st_dev & 0xFF,
         stat_buf.st_ino & 0xFFFF, myKey);

  // 使用生成的键值创建一个消息队列
  msgid = msgget(myKey, IPC_CREAT | 0666);
  if (msgid == -1) {
    perror("msgget failed");
    return 1;  // 处理错误
  }

  // 在这里可以添加更多的代码来发送或接收消息等操作...

  // 最后，记得清理资源，这里只是示例，实际应用中需要适当时候删除消息队列
  // if (msgctl(msgid, IPC_RMID, (struct msqid_ds*)0) == -1) {
  //     perror("msgctl(IPC_RMID) failed");
  // }

  return 0;
}
